/**
 * 
 */
package ua.kpi.javatrainee6.model.departments;

import ua.kpi.javatrainee6.model.assessment.Marks;
import ua.kpi.javatrainee6.model.curriculum.*;
import ua.kpi.javatrainee6.model.people.*;

import java.util.Date;

/**
 * Group entity, contains students, subjects and univer reference
 * Provides next functionality: you can view all members, subjects, section and
 * curriculum for particular group
 *
 */
public final class Group extends Department implements CurriculumPrintable, GroupInfo {
	
	private Student[] students;
	private Subjects subjects;
	private University univer;
	
	/**
	 * Main constructor
	 * @param title - Group name
	 * @param creationDate - creation date 
	 * @param univer - reference to University instance, for getting curriculum instance
	 */
	public Group(String title, Date creationDate, University univer) {
		super(title, creationDate);
		this.univer = univer;
	}
	
	/**
	 * Optional constructor, used now for automatic data generation, for more detailed description
	 * look in Department class
	 * @param univer - reference to University instance, for getting curriculum instance
	 */
	
	public Group(University univer) {
		super();
		this.univer = univer;
	}
	
	/**
	 * Enrolling students to the group, method is used by UniversityAdministrator
	 * @param students - students enrolled in group
	 */
	
	public void setStudents(Student[] students) {
		this.students = students;
	}
	
	/**
	 * Adding list of subjects to the group, method is used by UniversityAdministrator
	 * @param subjects - add
	 */
	
	public void setSubjects(Subjects subjects) {
		this.subjects = subjects;  
		for (Student student : students) {
			student.setMarks(new Marks(subjects));
		}
	}
	
	/**
	 * @return list of students in the group
	 */
	
	public Student[] getStudents() {
		return students;
	}
	/**
	 * @return list of subjects in the group
	 */
	
	public Subjects getSubjects() {
		return subjects;
	}
	
	/**
	 * method is used by Student instances to get curriculum
	 * @return university instance
	 */
	
	public University getUniver() {
		return univer;
	}
	
	/**
	 * Showing curriculum for group
	 */
	
	public void viewCurriculum() {
		Curriculum curriculum  = univer.getCurriculum();
		System.out.println("Curriculum for group " + getTitle());
		curriculum.printCurriculum(this);
	}
	
	/**
	 * Implementation of abstract method from Department class,
	 * group is not divided on sections
	 */
	
    public void viewAllSections() {
		System.out.printf("Group %s is not devided on sections\n", getTitle());
	}
    
    /**
     * Implementation of abstract method from Department class,
     * showing all members (students)
     */
	
	public void viewAllMembers() {
		System.out.println("All students of group " + getTitle());
		for (Student student : students) {
			System.out.println(student);
		}
	}
	
	/**
	 * Implementation of abstract method from Department class,
	 * viewing all subjects for this group
	 */
	
	public void viewAllSubjects() {
		System.out.println("All subjects in the group " + getTitle());
		for (Subject subject : subjects) {
			System.out.println(subject);
		}
	}
	
	/**
	 * Based on average score of student
	 * @return - average score of group
	 */
	public double calculateAverage() {
		double sum = 0.0;
		for (Student student : students) {
			sum += student.calculateAverage();
		}
		return sum / students.length;
	}
	
	@Override
	public String toString() {
		return String.format("Information about group:\n%s, %s", super.toString(), univer.getTitle());
	}
	
	@Override
	public boolean equals(Object otherObject) {
		if (! super.equals(otherObject)) {
			return false;
		}
		Group other = (Group) otherObject;
		if (univer.equals(other.univer)) {
			return true;
		} else {
			return false;
		}
	}
	
	public Student getStudent(int index) {
		return getStudents()[index];
	}
	
	public void performAssessment() {
		for (Student student : students) {
			for (Subject subject : subjects) {
				subject.performAssessment(student);
			}
		}	
	}
}